#include "stdafx.h"
#include <vector>
#pragma once;
using namespace std;

#define	TRUE				1
#define	FALSE				0
#define	EQUAL				-1
#define  ASCEND			true
#define	DESCEND			false

template<class T>
class Comparable
{
public:
	virtual void addComparable(Comparable<T>* cp) = 0;
	virtual int compare(const T& a,const T& b) = 0;   // Return: < 0 if equal, = 0 if false; > 0 if true  
};

template<class T>
class AndComparable:public Comparable<T>
{
private:
	vector<Comparable* > cp;
public:
	void addComparable(Comparable* cp)
	{
		this->cp.push_back(cp);
	}
	int compare(const T& a, const T& b)
	{
		for( int i = 0; i < (int)cp.size(); i++)
			if( cp[i]->compare(a, b) == TRUE )
				return TRUE;
			else if (cp[i]->compare(a, b) == FALSE )
				return FALSE;
		
		return EQUAL;
	}
};

template<class T>
class BasicCompareable:public Comparable<T>
{
protected:
	bool order;
public:
	BasicCompareable(bool order)
	{
		this->order = order;
	}
	BasicCompareable()
	{
		this->order = ASCEND;
	}
	void addComparable(Comparable* cp)
	{

	}
	int compare(const T& a, const T& b)
	{
		if(a > b )
			return (this->order == ASCEND ? TRUE : FALSE);
		else if(a < b)
			return (this->order == DESCEND ? TRUE : FALSE);

		return EQUAL;

	}
};

template<class T, class L>
class AdvanceCompareable:public Comparable<T>
{
protected:
	bool order;
	L (T::*p)();
	AdvanceCompareable();
public:
	AdvanceCompareable(bool order, L (T::*funcPtr)())
	{
		this->order = order;
		p =  funcPtr;
	}
	AdvanceCompareable(L (T::*funcPtr)())
	{
		this->order = ASCEND;
		p =  funcPtr;
	}
	void addComparable(Comparable* cp)
	{

	}
	int compare(const T& a, const T& b)
	{
		T A = a;
		T B = b;

		if((A.*p)() > (B.*p)())
			return (order == ASCEND ? TRUE : FALSE);
		else if((A.*p)() < (B.*p)())
			return (order == DESCEND ? TRUE : FALSE);

		return EQUAL;

	}
};